package com.coocaa.aries.jmeter.util;

import com.coocaa.aries.core.base.exception.ExceptionUtil;
import com.coocaa.aries.core.tool.InstanceUtil;
import com.coocaa.aries.core.tool.json.JsonUtil;
import com.coocaa.aries.jmeter.model.JmxTemplateModel;
import com.coocaa.aries.jmeter.model.KeyValuePair;
import com.coocaa.aries.jmeter.model.RequestModel;
import com.coocaa.aries.jmeter.model.ThreadGroupModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jdom2.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author : bijiahao
 * @date : 2019/4/16.
 * @description:
 */
@Slf4j
public class JmxFileParseUtil {

    private static final Logger log = LoggerFactory.getLogger(JmxFileParseUtil.class);


    public static JmxTemplateModel parseJmxModel(String filePath) {
        return parseJmxModel(new File(filePath));
    }

    public static JmxTemplateModel parseJmxModel(File file) {
        XmlUtil xmlUtil = new XmlUtil(file);
        Element root = xmlUtil.getRootEle();
        JmxTemplateModel jmxTemplateModel = new JmxTemplateModel();
        //解析线程组
        ThreadGroupModel threadGroupModel = parseThreadGroup(root);
        jmxTemplateModel.setThreadGroup(threadGroupModel);
        //解析请求头
        List<KeyValuePair> headers = parseHeaders(root);
        jmxTemplateModel.setHeaders(headers);
        //解析请求
        RequestModel requestModel = parseRequest(root);
        jmxTemplateModel.setRequest(requestModel);
        //解析请求URL参数
        List<KeyValuePair> urlParams = parseUrlParams(root);
        jmxTemplateModel.setUrlParams(urlParams);
        return jmxTemplateModel;
    }

    /**
     * 解析线程组
     *
     * @param root
     * @return
     */
    private static ThreadGroupModel parseThreadGroup(Element root) {
        ThreadGroupModel threadGroupModel = new ThreadGroupModel();

        Element threadGroupEle = null;
        try {
            threadGroupEle = root.getChildren("hashTree").get(0)
                    .getChildren("hashTree").get(0)
                    .getChild("ThreadGroup");
        } catch (Exception e) {
            log.error(ExceptionUtil.getStackTraceAsString(e));
            return threadGroupModel;
        }
        List<Element> stringPropEles = threadGroupEle.getChildren("stringProp");
        if (CollectionUtils.isNotEmpty(stringPropEles)) {
            Map<String, String> propMap = convert2Map(stringPropEles);
            threadGroupModel.setThreadNums(propMap.get("ThreadGroup.num_threads"));

            threadGroupModel.setRampTime(propMap.get("ThreadGroup.ramp_time"));
        }
        threadGroupModel.setLoops(getThreadLoop(threadGroupEle));
        return threadGroupModel;


    }

    private static String getThreadLoop(Element threadGroupEle) {
        Element element = null;
        try {
            element = threadGroupEle.getChild("elementProp").getChild("stringProp");
        } catch (Exception e) {
            log.error(ExceptionUtil.getStackTraceAsString(e));
            return "";
        }
        return getValue(element);


    }

    private static Map<String, String> convert2Map(List<Element> elementList) {
        Map<String, String> propMap = new HashMap<>(6);
        for (Element element : elementList) {
            propMap.put(getKey(element), getValue(element));
        }
        return propMap;
    }

    private static String getKey(Element element) {
        String key = element.getAttributeValue("name");
        return StringUtils.isNotBlank(key) ? key.trim() : "";
    }

    private static String getValue(Element element) {
        return element.getTextTrim();
    }

    /**
     * 解析请求头
     *
     * @param root
     * @return
     */
    private static List<KeyValuePair> parseHeaders(Element root) {
        List<KeyValuePair> pairList = InstanceUtil.newArrayList(4);
        Element ele = null;
        try {
            ele = root.getChildren("hashTree").get(0)
                    .getChildren("hashTree").get(0)
                    .getChildren("hashTree").get(0)
                    .getChild("HeaderManager").getChild("collectionProp");
        } catch (Exception e) {
            log.error(ExceptionUtil.getStackTraceAsString(e));
            return pairList;
        }

        List<Element> propList = ele.getChildren("elementProp");

        if (CollectionUtils.isNotEmpty(propList)) {
            for (Element element : propList) {
                String key = getKey(element);
                String value = getHeadValue(element);
                pairList.add(new KeyValuePair(key, value));
            }
        }
        return pairList;
    }

    private static String getHeadValue(Element element) {
        List<Element> stringProps = element.getChildren("stringProp");
        for (Element ele : stringProps) {
            if ("Header.value".equals(getKey(ele))) {
                return getValue(ele);
            }
        }
        return "";
    }

    private static String getUrlParamValue(Element element) {
        List<Element> stringProps = element.getChildren("stringProp");
        for (Element ele : stringProps) {
            if ("Argument.value".equals(getKey(ele))) {
                return getValue(ele);
            }
        }
        return "";
    }

    /**
     * 解析请求URL参数
     *
     * @param root
     * @return
     */
    private static List<KeyValuePair> parseUrlParams(Element root) {
        List<KeyValuePair> pairList = InstanceUtil.newArrayList(4);
        Element ele = null;
        try {
            ele = root.getChildren("hashTree").get(0)
                    .getChildren("hashTree").get(0)
                    .getChildren("hashTree").get(0)
                    .getChild("HTTPSamplerProxy").getChild("elementProp").getChild("collectionProp");

        } catch (Exception e) {
            log.error(ExceptionUtil.getStackTraceAsString(e));
            return pairList;
        }

        List<Element> propList = ele.getChildren("elementProp");

        if (CollectionUtils.isNotEmpty(propList)) {
            for (Element element : propList) {
                String key = getKey(element);
                String value = getUrlParamValue(element);
                pairList.add(new KeyValuePair(key, value));
            }
        }
        return pairList;
    }

    /**
     * 解析请求
     *
     * @param root
     * @return
     */
    private static RequestModel parseRequest(Element root) {
        RequestModel requestModel = new RequestModel();
        Element requestEle = null;
        try {
            requestEle = root.getChildren("hashTree").get(0)
                    .getChildren("hashTree").get(0).getChildren("hashTree").get(0).getChild("HTTPSamplerProxy");
        } catch (Exception e) {
            log.error(ExceptionUtil.getStackTraceAsString(e));
            return requestModel;
        }

        List<Element> stringPropEles = requestEle.getChildren("stringProp");

        if (CollectionUtils.isNotEmpty(stringPropEles)) {
            Map<String, String> propMap = convert2Map(stringPropEles);

            requestModel.setDomain(propMap.get("HTTPSampler.domain"));
            requestModel.setProtocol(propMap.get("HTTPSampler.protocol"));
            requestModel.setPort(propMap.get("HTTPSampler.port"));
            requestModel.setPath(propMap.get("HTTPSampler.path"));
            requestModel.setMethod(propMap.get("HTTPSampler.method"));
        }
        return requestModel;
    }

    public static void main(String[] args) {
//        String fp = "/Users/bijiahao/develop/jmeter/MyTestPlan.jmx";
        String fp = "/Users/bijiahao/develop/jmeter/jmeter-test-plan-224/224-test-plan-getTvosSixContent.jmx";

        JmxTemplateModel model = JmxFileParseUtil.parseJmxModel(fp);

        System.out.println(JsonUtil.obj2Json(model));
    }
}
